using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace LiveWriterBackup
{
    class BackupRestore
    {
        string temp_d;
        ArrayList ar;
        Settings _settings;
        string[] pluginAssemblies = { @"Software\Windows Live Writer\PluginAssemblies", @"Software\Microsoft\Windows Live\Writer\PluginAssemblies" };

        public BackupRestore(Settings settings)
        {
            this._settings = settings;
        }        

        public BackupRestore()
        {
            _settings = new Settings();
        }

        public static void CopyFolders(string source, string destination)
        {
            if (Directory.Exists(source))
            {
                DirectoryInfo di = new DirectoryInfo(source);

                CopyFiles(source, destination);

                foreach (DirectoryInfo d in di.GetDirectories())
                {
                    string newDir = Path.Combine(destination, d.Name);
                    Directory.CreateDirectory(newDir);

                    CopyFolders(d.FullName, newDir);
                }
            }
        }

        public static void CopyFiles(string source, string destination)
        {
            if (Directory.Exists(source))
            {
                DirectoryInfo di = new DirectoryInfo(source);
                FileInfo[] files = di.GetFiles();

                foreach (FileInfo f in files)
                {
                    f.IsReadOnly = false;
                    string sourceFile = f.FullName;
                    string destFile = Path.Combine(destination, f.Name);
                    if (!File.Exists(destFile))
                    {
                        File.Copy(sourceFile, destFile);
                    }
                }
            }
        }

        private List<string> GetPluginFolders()
        {
            List<string> folders = new List<string>();

            foreach (string ass in pluginAssemblies)
            {
                RegistryKey local = Registry.LocalMachine;
                RegistryKey user = Registry.CurrentUser;
                local = local.OpenSubKey(ass);
                user = user.OpenSubKey(ass);
                if (local != null)
                {
                    foreach (string key in local.GetValueNames())
                    {
                        folders.Add(local.GetValue(key).ToString());
                    }
                }
                if (user != null)
                {
                    foreach (string key in user.GetValueNames())
                    {
                        folders.Add(user.GetValue(key).ToString());
                    }
                }
            }

            return folders;
        }

        public void doRestore(string temp_d)
        {
            this.temp_d = temp_d;

            try
            {
                ///////////////////////////////////////
                //
                // Restore User Settings
                //
                ///////////////////////////////////////

                string[] regfiles = Directory.GetFiles(temp_d, "*.reg");
                if (regfiles.Length > 0)
                {
                    foreach (string s in regfiles)
                    {
                        setRegistry(s);
                    }
                }

                ///////////////////////////////////////
                //
                // Move Blog Templates
                //
                ///////////////////////////////////////

                if (Directory.Exists(temp_d + "\\blogtemplates"))
                {
                    string template_folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Windows Live Writer\\blogtemplates";
                    if (Directory.Exists(template_folder))
                    {
                        Directory.Delete(template_folder, true);
                        Directory.CreateDirectory(template_folder);
                    }
                    CopyFolders(temp_d + "\\blogtemplates", template_folder);
                }


                ///////////////////////////////////////
                //
                // Move blog posts
                //
                ///////////////////////////////////////

                if (Directory.Exists(temp_d + "\\My Weblog Posts"))
                {
                    string documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    string restore_blogs_path = documents + "\\My Weblog Posts";
                    if (Directory.Exists(restore_blogs_path))
                    {
                        Directory.Delete(restore_blogs_path, true);
                    }
                    CopyFolders(temp_d + "\\My Weblog Posts", restore_blogs_path);
                }

                ////////////////////////////////////////
                //
                // Move Plugins
                //
                ////////////////////////////////////////

                if (Directory.Exists(temp_d + "\\Plugins"))
                {
                    string progfiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
                    if (File.Exists(progfiles + "\\Windows Live\\Writer\\WindowsLiveWriter.exe"))
                    {
                        if (Directory.Exists(progfiles + "\\Windows Live\\Writer\\Plugins"))
                        {
                            Directory.Delete(progfiles + "\\Windows Live\\Writer\\Plugins", true);
                        }
                        Directory.CreateDirectory(progfiles + "\\Windows Live\\Writer\\Plugins");
                        if (Directory.Exists(temp_d + "\\Plugins\\Plugins"))
                            CopyFiles(temp_d + "\\Plugins\\Plugins", progfiles + "\\Windows Live\\Writer\\Plugins");
                        else
                            CopyFiles(temp_d + "\\Plugins", progfiles + "\\Windows Live\\Writer\\Plugins");
                    }
                    else if (File.Exists(progfiles + "\\Windows Live Writer\\WindowsLiveWriter.exe"))
                    {
                        if (Directory.Exists(progfiles + "\\Windows Live Writer\\Plugins"))
                        {
                            Directory.Delete(progfiles + "\\Windows Live Writer\\Plugins", true);
                        }
                        Directory.CreateDirectory(progfiles + "\\Windows Live Writer\\Plugins");
                        if (Directory.Exists(temp_d + "\\Plugins\\Plugins"))
                            CopyFiles(temp_d + "\\Plugins\\Plugins", progfiles + "\\Windows Live\\Writer\\Plugins");
                        else
                            CopyFiles(temp_d + "\\Plugins", progfiles + "\\Windows Live\\Writer\\Plugins");
                    }

                    if (Directory.Exists(temp_d + "\\Plugins\\PluginAssemblies"))
                    {
                        List<string> pluginassemblies = GetPluginFolders();
                        if (pluginassemblies.Count != 0)
                        {
                            string paf = temp_d + "\\Plugins\\PluginAssemblies";
                            string path_temp = "";
                            foreach (string plugin in pluginassemblies)
                            {
                                string path = Path.GetFullPath(plugin).Substring(0, plugin.IndexOf(Path.GetFileName(plugin)));
                                path_temp = paf + "\\" + path.Substring(3);
                                if (!Directory.Exists(path))
                                {
                                    try
                                    {
                                        Directory.CreateDirectory(path);
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show("There was an error: " + ex.Message);
                                    }
                                }
                                CopyFiles(path_temp, path);
                            }
                        }
                    }
                }

                ////////////////////////////////
                //
                //   Migrate settings to beta 3
                //
                ////////////////////////////////

                if (File.Exists(temp_d + "\\writer.reg"))
                {
                    RegistryKey key = Registry.CurrentUser;
                    key = key.OpenSubKey("Software\\Windows Live Writer", true);
                    if (key.GetSubKeyNames().Length > 1)
                    {
                        RegistryKey newkey = Registry.CurrentUser;
                        newkey = newkey.OpenSubKey("Software\\Microsoft\\Windows Live\\Writer", true);
                        RecurseCopyKey(key, newkey);
                        foreach (string keyname in key.GetSubKeyNames())
                        {
                            if (keyname != "PluginAssemblies")
                            {
                                key.DeleteSubKeyTree(keyname);
                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                LiveWriterBackupWPF.WLBDebug.WriteToFile(ex.Message);
                LiveWriterBackupWPF.WLBDebug.WriteToFile(ex.ToString());
            }

        }

        private void RecurseCopyKey(RegistryKey sourceKey, RegistryKey destinationKey)
        {
            //copy all the values
            foreach (string valueName in sourceKey.GetValueNames())
            {
                object objValue = sourceKey.GetValue(valueName);
                RegistryValueKind valKind = sourceKey.GetValueKind(valueName);
                destinationKey.SetValue(valueName, objValue, valKind);
            }

            //For Each subKey 
            //Create a new subKey in destinationKey 
            //Call myself 
            foreach (string sourceSubKeyName in sourceKey.GetSubKeyNames())
            {
                RegistryKey sourceSubKey = sourceKey.OpenSubKey(sourceSubKeyName);
                RegistryKey destSubKey = destinationKey.CreateSubKey(sourceSubKeyName);
                RecurseCopyKey(sourceSubKey, destSubKey);
            }
        }
        
        private void setRegistry(string temp_r)
        {
            System.Diagnostics.Process process1;

            process1 = new System.Diagnostics.Process();

            //Do not receive an event when the process exits.

            process1.EnableRaisingEvents = false;


            System.Diagnostics.Process.Start("regedit.exe", "/s " + temp_r);

            process1.Close();
        }

    }
}
